home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / CC_C / 0294.ZIP / SHELL2.ARC / MORE.C < prev    next >
C/C++ Source or Header  |  1985-08-08  |  5KB  |  288 lines

  1. #include "gen.h"
  2. #include <stdio.h>
  3. #include <fcntl.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7.  
  8. #include <dos.h>
  9.  
  10.  
  11. /*
  12.  *    more:  a Unix(tm) like more command for MS-DOS
  13.  *
  14.  *  by  Douglas Orr
  15.  *      Textset Inc.
  16.  *      Ann Arbor, Michigan
  17.  *
  18.  *  Copyright (c) 1985 Textset.   All rights reserved.
  19.  *
  20.  *  This program may be freely distributed, but not sold for profit.
  21.  *
  22.  */
  23.  
  24.  
  25. /*
  26.  *    To compile:   msc -Ze more.c
  27.  *
  28.  *  Code in chin must be changed if you go to a large memory model.
  29.  */
  30.  
  31. Local char  esc = '\033';
  32. Local char    ctl_z = '\032';
  33.  
  34. Local FILE * con = NULL;
  35.  
  36. main( argc, argv )
  37. int    argc;
  38. char * argv[];
  39.     {
  40.     int fd;
  41.     struct  stat statb;
  42.  
  43.     while( --argc )
  44.         {
  45.         if( (*++argv)[0] == '-' )
  46.             switch( (*argv)[1] )
  47.                 {
  48.                 default:
  49.                     fprintf( stderr, "invalid argument %s\n", *argv );
  50.                     exit(1);
  51.                 }
  52.         else
  53.             break;
  54.         }
  55.  
  56.  
  57.     if( argc == 0 )
  58.         {
  59.  
  60.         more( NULL, fileno(stdin), 0L);
  61.         exit( 0 );
  62.  
  63.         }
  64.     else
  65.     while( argc-- )
  66.         {
  67.  
  68.         if( (fd = open( *argv, O_RDONLY+O_BINARY )) < 0 )
  69.             fprintf( stderr, "couldn't open %s\n", *argv );
  70.         else
  71.             {
  72.             statb.st_size = 0;  /* just in case fstat fails */
  73.             fstat( fd, &statb );
  74.             more( *argv, fd, statb.st_size );
  75.             close( fd );
  76.             }
  77.         argv++;
  78.         if( argc )
  79.             {
  80.             printf( "%c[7m  Next file: %s  %c[0m", esc, *argv, esc );
  81.             chin();
  82.             printf( "\r%c[K", esc );
  83.             }
  84.  
  85.         }
  86.  
  87.     }
  88.  
  89. Local char buffer[BUFSIZ];
  90. Local int bufp = 0;
  91. Local long pos = 0;
  92. Local int cnt = 0;
  93. Local int eof;
  94.  
  95. initfile()
  96.     {
  97.     bufp = pos = cnt = 0;
  98.     eof = False;
  99.     }
  100.  
  101. long
  102. getline( fd, line, linesize )
  103. int    fd;
  104. char    * line;
  105. int    linesize;
  106.     {
  107.  
  108.     int    linep;
  109.     bool  eol;
  110.  
  111.     if( eof )
  112.         return( -1 );
  113.  
  114.     for( linep=0; linep < linesize; )
  115.         {
  116.  
  117.         if( bufp >= cnt )
  118.             {
  119.             pos += cnt;
  120.             bufp = 0;
  121.             if( (cnt = read( fd, buffer, sizeof buffer )) == 0 )
  122.                 {
  123.                 if( linep != 0 )
  124.                     {
  125.                     eof = True;
  126.                     break;
  127.                     }
  128.                 return( -1 );
  129.                 }
  130.             }
  131.  
  132.         /*  newline signals eol  */
  133.         if( buffer[bufp] == '\n' )
  134.             {
  135.             bufp++;
  136.             break;
  137.             }
  138.         else
  139.         if( buffer[bufp] == ctl_z )
  140.             {
  141.             eof = True;
  142.             break;
  143.             }
  144.         else
  145.             {
  146.             /*  ignore crs  */
  147.             if( buffer[bufp] != '\r' )
  148.                 line[linep++] = buffer[bufp];
  149.             bufp++;
  150.             }
  151.  
  152.         }
  153.  
  154.     line[linep] = '\0';
  155.     return( pos + bufp );
  156.  
  157.     }
  158.  
  159. more(fname, fd, size)
  160. char * fname;
  161. int fd;
  162. long size;
  163.     {
  164.     int    cnt;
  165.     char buf[80];
  166.     long pos;
  167.     long lineno = 0;
  168.  
  169.     initfile();
  170.  
  171.     if( fname )
  172.         {
  173.         printf( "%c[1m  More:  File <%s> %c[0m\n", esc, fname, esc );
  174.         cnt = 1;
  175.         }
  176.     else
  177.         cnt = 0;
  178.  
  179.     while( (pos = getline( fd, buf, sizeof(buf)-1 )) >= 0 )
  180.         {
  181.         printf( "%s\n", buf );
  182.         lineno++;
  183.         if( (++cnt % 24) == 0 )
  184.             {
  185.             bool done;
  186.  
  187.             if( size )
  188.                 printf( "%c[7m  -More(%ld%%)- %c[0m", esc, 
  189.                     ((pos*100)/size), esc );
  190.             else
  191.                 printf( "%c[7m  -More-  %c[0m", esc, esc );
  192.  
  193.             for( done=False; !done; )
  194.                 {
  195.                 done = True;
  196.                 switch( chin() )
  197.                     {
  198.                     case ' ':
  199.                         cnt = 0; 
  200.                         break;
  201.                     case '\r':
  202.                     case '\n':
  203.                         cnt--;
  204.                         break;
  205.                     case 'q':
  206.                         printf( "\n" );
  207.                         exit(0);
  208.                     case 'v':
  209.                         sprintf( buf, "v %s", fname );
  210.                         system( buf );
  211.                         cnt--;
  212.                         break;
  213.                     case ':':
  214.                         switch( chin() )
  215.                             {
  216.                             case 'n':
  217.                             printf( "\r%c[K", esc );
  218.                             return;
  219.                             }
  220.                     default:
  221.                         done = False;
  222.                         break;
  223.                     }
  224.                 }
  225.             printf( "\r%c[K", esc );
  226.             }
  227.  
  228.         }
  229.  
  230.     }
  231.  
  232. /*
  233.  *  !! Today's mystery:  I have tried every way that I can think of
  234.  *     to open con: in binary mode, using uSoft routines, and I just
  235.  *     can't get it.  I open with the right flags, using open or fopen,
  236.  *     and the file descriptor comes up as non-binary when polled via
  237.  *     ioctl.  Even "setmode" doesn't work.  What gives?
  238.  *
  239.  *     the result is what follows:
  240.  *
  241.  */
  242.  
  243. chin()
  244.     {
  245.     Local int confd = -1;
  246.  
  247.     union REGS regs;
  248.     char far * buf;            /* need -Ze to compile  */
  249.     char buffer[1];
  250.  
  251.     if( confd < 0 )
  252.         {
  253.  
  254.         if( (confd = open("con", O_RDONLY)) < 0 )
  255.             {
  256.             fprintf( stderr, "couldn't open con:\n" );
  257.             exit(1);
  258.             }
  259.  
  260.         /*  get the current ioctl bits for con: */
  261.         regs.h.ah = 0x44;
  262.         regs.h.al = 0;
  263.         regs.x.bx = confd;
  264.         intdos( ®s, ®s );
  265.  
  266.         /* flip on binary mode */
  267.         regs.h.ah = 0x44;
  268.         regs.h.al = 1;
  269.         regs.x.bx = confd;
  270.         regs.x.dx |= 0x20;
  271.         regs.x.dx &= ~(0x8010);
  272.         intdos( ®s, ®s );
  273.  
  274.         }
  275.  
  276.     /*  read seems to be a bit problematical, also  */
  277.     buf = buffer;
  278.     regs.h.ah = 0x3f;
  279.     regs.x.bx = confd;
  280.     /*  !! small model - ds is the current ds  */
  281.     regs.x.dx = FP_OFF(buf);
  282.     regs.x.cx = 1;
  283.     intdos( ®s, ®s );
  284.  
  285.     return( buf[0] );
  286.  
  287.     }
  288.